/*
 * Copyright (c) 2018, dreamkaylee@foxmail.com All Rights Reserved.
 */

package com.common.shiro.filter;

import java.io.IOException;
import java.util.Set;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.util.StringUtils;

import com.common.model.AjaxJson;
import com.common.util.HtmlUtil;
import com.common.util.JsonUtils;

/**
 * 重写shiro认证过滤器
 * 
 * @author limk
 * @date 2018年2月13日 上午9:47:46
 * @version 1.0
 */
public class RoleAuthorizationFilter extends AuthorizationFilter {

	@Override
	protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {

		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;

		Subject subject = getSubject(request, response);

		if (subject.getPrincipal() == null) {
			if (HtmlUtil.isAjaxRequest(httpRequest)) {
				HtmlUtil.writeJson(httpResponse, JsonUtils.toJSON(new AjaxJson(false, "您尚未登录或登录时间过长，请重新登录！")));
			} else {
				saveRequestAndRedirectToLogin(request, response);
			}
		} else {
			if (HtmlUtil.isAjaxRequest(httpRequest)) {
				HtmlUtil.writeJson(httpResponse, JsonUtils.toJSON(new AjaxJson(false, "您没有足够的权限执行该操作！")));
			} else {
				String unauthorizedUrl = getUnauthorizedUrl();
				if (StringUtils.hasText(unauthorizedUrl)) {
					WebUtils.issueRedirect(request, response, unauthorizedUrl);
				} else {
					WebUtils.toHttp(response).sendError(401);
				}
			}
		}
		return false;
	}

	@Override
	protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
			throws Exception {
		Subject subject = getSubject(request, response);
		String[] rolesArray = (String[]) mappedValue;

		if (rolesArray == null || rolesArray.length == 0) {
			return true;
		}

		Set<String> roles = CollectionUtils.asSet(rolesArray);
		for (String role : roles) {
			if (subject.hasRole(role)) {
				return true;
			}
		}
		return false;
	}

}
